package com.example.springbootblog.common.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import lombok.extern.slf4j.Slf4j;


import javax.crypto.SecretKey;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Map;


/**
 * 生成令牌和校验令牌相关单元
 */
@Slf4j
public class JwtUtil {
    /**
     * 这里不要每次都生成密钥
     * 自己固定一个密钥，既是生成
     * 同时也需要验证
     */
    //        密钥的原密文
    private static final String secret = "k3Pmc4Szw4jhEd6ydFYYaTCpISR8EUEspqE2JcRZz5Y=";


    //        密文转化为设置密钥
    private static Key key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secret));

    //        设置超时时间
    private static long expiration = 5 *  60  * 60 * 1000;

    public static String genToken(Map<String, Object> map) {
        return Jwts.builder()   //构造器生成
                .setClaims(map)  // 设置载荷
                .signWith(key)   // 设置签名
                .setIssuedAt(new Date()) // 设置签名时间
                .setExpiration(new Date(System.currentTimeMillis() + expiration))  //设置超时时间
                .compact(); // 压缩成字符串类型的令牌
    }

    //        开始校验
    public static Claims checkToken(String token) {
        // 校验参数
        if (token == null) {
            return null;
        }

//            生成一个校验器
        JwtParser build = Jwts.parserBuilder().setSigningKey(key).build();

//            设置一个body 用来接收
        Claims body = null;
        try {
//                    根据是否生成的载荷， 判断该令牌是否正确
            body = build.parseClaimsJws(token).getBody();
            return body;
        } catch (ExpiredJwtException e) {
            log.error("生成的令牌超时...");
        } catch (SignatureException e) {
            log.error("生成的签名错误...");
        } catch (Exception e) {
            log.error("验证错误...");
        }

        return null;
    }

    /**
     *
     * 虽然项目中未真正去用到这个方法
     * 但方便开发去生成一个固定的密钥
     * @return
     * @throws NoSuchAlgorithmException
     */
    //        生成密文
    public static String genSecret() throws NoSuchAlgorithmException {
        SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
        String secret = Encoders.BASE64.encode(secretKey.getEncoded());
        return secret;
    }
}
